﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace XKControlLib
{
    public partial class CButton : Button
    {
        private Color _borderColor = Color.FromArgb(23, 169, 254);
        private bool mouseover = false;//鼠标经过

        public bool IsCircle { get; set; }
        public int CircleSize { get; set; } = 100;
        public Point CirclePoint { get; set; } = new Point(0, 0);
        public Color _backColor { get; set; } = Color.FromArgb(234, 247, 254);
        public Color baseColor { get; set; } = Color.FromArgb(166, 222, 255);
        public Color borderColor { get; set; } = Color.FromArgb(23, 169, 254);

        public CButton() : base()
        {
            SetStyles();
        }

        private void SetStyles()
        {
            base.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            base.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            mouseover = false;
            base.OnMouseLeave(e);
            base.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            DrawContrl(e);

        }

        private void DrawContrl(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.Clear(this.BackColor);
            Rectangle rect = e.ClipRectangle;
            rect = new Rectangle(rect.X, rect.Y, rect.Width - 1, rect.Height - 2);
            if (mouseover)
            {
                if (Focused)
                {
                    if (IsCircle)
                    {
                        DrawCircleButton(Text, g, CirclePoint, CircleSize, ButtonStyle.ButtonFocuseAndMouseOver);
                        return;
                    }
                    //DrawRoundButton(this.Text, g, rect, ButtonStyle.ButtonFocuseAndMouseOver);
                    RenderBackgroundInternal(e.Graphics, ClientRectangle, borderColor, borderColor, 0.45f, true, LinearGradientMode.Vertical);
                    DrawText(e.Graphics, ClientRectangle, false);
                    return;
                }
                if (IsCircle)
                {
                    DrawCircleButton(Text, g, CirclePoint, CircleSize, ButtonStyle.ButtonMouseOver);
                    return;
                }
                //DrawRoundButton(this.Text, g, rect, ButtonStyle.ButtonMouseOver);
                RenderBackgroundInternal(e.Graphics, ClientRectangle, borderColor, borderColor, 0.45f, true, LinearGradientMode.Vertical);
                DrawText(e.Graphics, ClientRectangle, false);
                return;
            }
            if (Focused)
            {
                if (IsCircle)
                {
                    DrawCircleButton(Text, g, CirclePoint, CircleSize, ButtonStyle.ButtonFocuse);
                    return;
                }
                //DrawRoundButton(this.Text, g, rect, ButtonStyle.ButtonFocuse);
                RenderBackgroundInternal(e.Graphics, ClientRectangle, borderColor, borderColor, 0.45f, true, LinearGradientMode.Vertical);
                DrawText(e.Graphics, ClientRectangle, false);
                return;
            }
            if (IsCircle)
            {
                DrawCircleButton(Text, g, CirclePoint, CircleSize, ButtonStyle.ButtonNormal);
                return;
            }
            //DrawRoundButton(this.Text, g, rect, ButtonStyle.ButtonNormal);


            RenderBackgroundInternal(e.Graphics, ClientRectangle, baseColor, borderColor, 0.45f, true, LinearGradientMode.Vertical);
            DrawText(e.Graphics, ClientRectangle, false);

        }
        private static readonly int Radius = 8;
        private void DrawText(Graphics g, Rectangle tabRect, bool hasImage)
        {
            Rectangle textRect = tabRect;
            RectangleF newTextRect;
            StringFormat sf;
            switch (this.TextAlign)
            {
                case ContentAlignment.TopCenter:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.BottomCenter:
                    if (hasImage)
                    {
                        textRect.X = tabRect.X + Radius / 2 + tabRect.Height - 2;
                        textRect.Width = tabRect.Width - Radius - tabRect.Height;
                    }

                    TextRenderer.DrawText(
                        g,
                        this.Text,
                        this.Font,
                        textRect,
                        this.ForeColor);
                    break;
                case ContentAlignment.TopLeft:
                case ContentAlignment.BottomLeft:
                case ContentAlignment.MiddleLeft:
                    if (hasImage)
                    {
                        textRect.Height = tabRect.Height - tabRect.Width + 2;
                    }
                    g.TranslateTransform(textRect.X, textRect.Bottom);
                    g.RotateTransform(270F);
                    sf = new StringFormat(StringFormatFlags.NoWrap);
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.Character;
                    newTextRect = textRect;
                    newTextRect.X = 0;
                    newTextRect.Y = 0;
                    newTextRect.Width = textRect.Height;
                    newTextRect.Height = textRect.Width;
                    using (Brush brush = new SolidBrush(this.ForeColor))
                    {
                        g.DrawString(
                            this.Text,
                            this.Font,
                            brush,
                            newTextRect,
                            sf);
                    }
                    g.ResetTransform();
                    break;
                case ContentAlignment.TopRight:
                case ContentAlignment.MiddleRight:
                case ContentAlignment.BottomRight:
                    if (hasImage)
                    {
                        textRect.Y = tabRect.Y + Radius / 2 + tabRect.Width - 2;
                        textRect.Height = tabRect.Height - Radius - tabRect.Width;
                    }
                    g.TranslateTransform(textRect.Right, textRect.Y);
                    g.RotateTransform(90F);
                    sf = new StringFormat(StringFormatFlags.NoWrap);
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Trimming = StringTrimming.Character;
                    newTextRect = textRect;
                    newTextRect.X = 0;
                    newTextRect.Y = 0;
                    newTextRect.Width = textRect.Height;
                    newTextRect.Height = textRect.Width;
                    using (Brush brush = new SolidBrush(this.ForeColor))
                    {
                        g.DrawString(
                            this.Text,
                            this.Font,
                            brush,
                            newTextRect,
                            sf);
                    }
                    g.ResetTransform();
                    break;
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            mouseover = true;
            base.OnMouseEnter(e);
            base.Invalidate();
        }

        /// <summary>
        /// 绘制圆形按钮（用法同矩形按钮）
        /// </summary>
        /// <param name="text"></param>
        /// <param name="g"></param>
        /// <param name="Location"></param>
        /// <param name="r"></param>
        /// <param name="btnStyle"></param>
        public void DrawCircleButton(string text, Graphics g, Point Location, int r, ButtonStyle btnStyle)
        {
            Graphics Gcircle = g;

            Rectangle rect = new Rectangle(Location.X, Location.Y, r, r);
            Pen p = new Pen(new SolidBrush(Color.Black));
            Gcircle.SmoothingMode = SmoothingMode.AntiAlias;
            Gcircle.DrawEllipse(p, rect);
            if (btnStyle == ButtonStyle.ButtonFocuse)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#338FCC")), rect);
            }
            else if (btnStyle == ButtonStyle.ButtonMouseOver)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
            }
            else if (btnStyle == ButtonStyle.ButtonFocuseAndMouseOver)
            {
                Gcircle.FillEllipse(new SolidBrush(ColorTranslator.FromHtml("#EAC100")), rect);
            }

            p.DashStyle = DashStyle.Dash;
            if (btnStyle != ButtonStyle.ButtonNormal)
            {
                Gcircle.DrawEllipse(p, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));//虚线框
            }
            Gcircle.FillEllipse(new SolidBrush(Color.WhiteSmoke), new Rectangle(rect.X + 3, rect.Y + 3, rect.Width - 6, rect.Height - 6));
            StringFormat sf = CAlignToSF(TextAlign);
            Gcircle.DrawString(text, this.Font, new SolidBrush(ForeColor), rect, sf);
            p.Dispose();
        }

        /// <summary> 
        /// 绘制圆角按钮
        /// </summary> 
        /// <param name="Text">要绘制的文字</param>
        /// <param name="g">Graphics 对象</param> 
        /// <param name="rect">要填充的矩形</param> 
        /// <param name="btnStyle"></param>
        public void DrawRoundButton(string Text, Graphics g, Rectangle rect, ButtonStyle btnStyle)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;//消除锯齿
            Rectangle rectangle = rect;
            Brush b = new SolidBrush(Color.Gray);
            if (btnStyle == ButtonStyle.ButtonFocuse)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#338FCC"));
            }
            else if (btnStyle == ButtonStyle.ButtonMouseOver)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
            }
            else if (btnStyle == ButtonStyle.ButtonFocuseAndMouseOver)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
            }
            g.DrawPath(new Pen(b), GetRoundRectangle(rectangle, 2));
            rectangle = new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4);
            Pen p = new Pen(Color.Black, 0.5f);
            p.DashStyle = DashStyle.Dash;
            if (btnStyle == ButtonStyle.ButtonFocuse || btnStyle == ButtonStyle.ButtonFocuseAndMouseOver)
            {
                g.DrawRectangle(p, rectangle);//虚线框
            }

            Brush BackColor = new SolidBrush(Color.FromArgb(236, 236, 236));
            if (btnStyle == ButtonStyle.ButtonFocuse)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#338FCC"));
            }
            else if (btnStyle == ButtonStyle.ButtonMouseOver)
            {
                BackColor = new SolidBrush(Color.FromArgb(60, 127, 177));
            }
            else if (btnStyle == ButtonStyle.ButtonFocuseAndMouseOver)
            {
                b = new SolidBrush(ColorTranslator.FromHtml("#C6A300"));
            }


            g.FillRectangle(BackColor, rectangle);//白色背景
            StringFormat sf = CAlignToSF(this.TextAlign);
            g.DrawString(Text, this.Font, new SolidBrush(ForeColor), rectangle, sf);
            p.Dispose();
            b.Dispose();
            g.SmoothingMode = SmoothingMode.Default;
        }
        private StringFormat CAlignToSF(ContentAlignment align)
        {
            StringFormat format = new StringFormat();
            switch (align)
            {
                case ContentAlignment.TopRight:
                    format.Alignment = StringAlignment.Far;
                    format.LineAlignment = StringAlignment.Near;
                    break;
                case ContentAlignment.TopLeft:
                    format.Alignment = StringAlignment.Near;
                    format.LineAlignment = StringAlignment.Near;
                    break;
                case ContentAlignment.TopCenter:
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Near;
                    break;
                case ContentAlignment.MiddleRight:
                    format.Alignment = StringAlignment.Far;
                    format.LineAlignment = StringAlignment.Center;
                    break;
                case ContentAlignment.MiddleLeft:
                    format.Alignment = StringAlignment.Near;
                    format.LineAlignment = StringAlignment.Center;
                    break;
                case ContentAlignment.MiddleCenter:
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Center;
                    break;
                case ContentAlignment.BottomRight:
                    format.Alignment = StringAlignment.Far;
                    format.LineAlignment = StringAlignment.Far;
                    break;
                case ContentAlignment.BottomLeft:
                    format.Alignment = StringAlignment.Near;
                    format.LineAlignment = StringAlignment.Far;
                    break;
                case ContentAlignment.BottomCenter:
                    format.Alignment = StringAlignment.Center;
                    format.LineAlignment = StringAlignment.Far;
                    break;
            }
            return format;
        }
        /// <summary> 
        /// 根据普通矩形得到圆角矩形的路径 
        /// </summary> 
        /// <param name="rectangle">原始矩形</param> 
        /// <param name="r">半径</param> 
        /// <returns>图形路径</returns> 
        private GraphicsPath GetRoundRectangle(Rectangle rectangle, int r)
        {
            int l = 2 * r;
            // 把圆角矩形分成八段直线、弧的组合，依次加到路径中  
            GraphicsPath gp = new GraphicsPath();
            gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);

            gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);

            gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);

            gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
            return gp;
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            CircleSize = this.Size.Height > this.Size.Width ? this.Size.Width - 1 : this.Size.Height - 1;
            base.OnSizeChanged(e);
        }

        private Color GetColor(Color colorBase, int a, int r, int g, int b)
        {
            int a0 = colorBase.A;
            int r0 = colorBase.R;
            int g0 = colorBase.G;
            int b0 = colorBase.B;

            if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
            if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
            if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
            if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }

            return Color.FromArgb(a, r, g, b);
        }
        private void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, float basePosition, bool drawBorder, LinearGradientMode mode)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(
               rect, Color.Transparent, Color.Transparent, mode))
            {
                Color[] colors = new Color[4];
                colors[0] = GetColor(baseColor, 0, 35, 24, 9);
                colors[1] = GetColor(baseColor, 0, 13, 8, 3);
                colors[2] = baseColor;
                colors[3] = GetColor(baseColor, 0, 68, 69, 54);

                ColorBlend blend = new ColorBlend();
                blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
                blend.Colors = colors;
                brush.InterpolationColors = blend;
                g.FillRectangle(brush, rect);
            }
            if (baseColor.A > 80)
            {
                Rectangle rectTop = rect;
                if (mode == LinearGradientMode.Vertical)
                {
                    rectTop.Height = (int)(rectTop.Height * basePosition);
                }
                else
                {
                    rectTop.Width = (int)(rect.Width * basePosition);
                }
                using (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
                {
                    g.FillRectangle(brushAlpha, rectTop);
                }
            }

            if (drawBorder)
            {
                var rect2 = new Rectangle(rect.X, rect.Y, rect.Width - 1, rect.Height - 1);
                using (Pen pen = new Pen(borderColor))
                {
                    g.DrawRectangle(pen, rect2);
                }
                var rr = RibbonProfessionalRenderer.RoundRectangle(rect2, 2);
                //using (var p = new Pen(borderColor))
                //{
                //    g.DrawPath(p, GetRoundRectangle(rect2, 2));
                //}
            }
        }
       
    }

    public enum ButtonStyle
    {
        /// <summary>
        /// 正常为选中按钮
        /// </summary>
        ButtonNormal,
        /// <summary>
        /// 获得焦点的按钮
        /// </summary>
        ButtonFocuse,
        /// <summary>
        /// 鼠标经过样式
        /// </summary>
        ButtonMouseOver,
        /// <summary>
        /// 获得焦点并鼠标经过
        /// </summary>
        ButtonFocuseAndMouseOver
    }
}
